`timescale 1ns / 1ns

module RD_interface(

input i_clk, 
input i_rst,

output wire o_RDflag, 
input rd_trig, 
input [7:0] RD_addr,

output reg [7:0]o_read_data, 

output wire o_RD_finish,

input [7:0] i_sja1000_data_rd, 
output wire o_chip_oe, 
output wire [7:0] o_sja1000_data_wr, 
output wire o_sja1000_rd_n,
output wire o_sja1000_ale,
output wire o_sja1000_cs_n,
output wire o_sja1000_dir_1out

);





 localparam IDLER = 16'b0000_0000_0000_0000;
 localparam S1R = 		16'b0000_0000_0000_0001;
 localparam S2R = 		16'b0000_0000_0000_0010;
 localparam S3R = 		16'b0000_0000_0000_0100;
 localparam S4R = 		16'b0000_0000_0000_1000;
 localparam S5R = 		16'b0000_0000_0001_0000;
 localparam S6R = 		16'b0000_0000_0010_0000;
 localparam S7R = 		16'b0000_0000_0100_0000;
 localparam S8R = 		16'b0000_0000_1000_0000;
 localparam S9R = 		16'b0000_0001_0000_0000;
 localparam S10R = 	16'b0000_0010_0000_0000;
 localparam S11R = 	16'b0000_0100_0000_0000;
 localparam S12R = 	16'b0000_1000_0000_0000;
 localparam S13R = 	16'b0001_0000_0000_0000;
 localparam S14R = 	16'b0010_0000_0000_0000;
 localparam S15R = 	16'b0100_0000_0000_0000;
 localparam S16R = 	16'b1000_0000_0000_0000;





reg rd_trig0, rd_trig1;

always@(posedge i_clk) 
begin

	if(i_rst) 
		begin
			rd_trig1 <= 1'd0; 
			rd_trig0 <= 1'd0;
		end 
	
	else 
		begin 
			rd_trig1 <= rd_trig0; 
			rd_trig0 <= rd_trig; 
		end 
		
end 

(* KEEP="TRUE" *)(* S="YES" *)wire rd_trig_r;
assign rd_trig_r = (~rd_trig0) && rd_trig1;



reg RDflag, RD_finish;
reg [7:0] RDaddr;
always@(posedge i_clk)
begin

	if(i_rst) 
		begin 
			RDaddr <= 8'd0;  
		end
	
	else if(rd_trig)
		begin 
			RDaddr <= RD_addr; 
		end 
	
end 















reg [7:0] read_data, sja1000_data_wr;
reg chip_oe, sja1000_cs_n, sja1000_dir_1out;
reg sja1000_rd_n, sja1000_ale;




 (* KEEP="TRUE" *)(* S="YES" *) reg [15:0] st, st_temp;
 always@(posedge i_clk) 
 begin
 
	 if(i_rst) 
		begin 
			st_temp <= 16'd0;
		end
		
	 else 
		begin
			st_temp <= st;
		end 
		
end 



		
		
 always@(posedge i_clk) 
 begin
 
	 if(i_rst) 
		begin 
			chip_oe <= 1'b0; 
			read_data <= 8'd0; 
			sja1000_dir_1out <= 1'b1; 
			sja1000_ale <= 1'b0; 
			sja1000_rd_n <= 1'b1; 
			sja1000_cs_n <= 1'b1;
			RDflag <= 1'b0; 
			RD_finish<= 1'b0; 
			st <= IDLER; 
		end
		
	 else 
		begin
		
			case(st)
			
				IDLER:
					begin
						chip_oe <= 1'b0; 
						sja1000_dir_1out <= 1'b1;
						sja1000_ale <= 1'b0; 
						sja1000_rd_n <= 1'b1; 
						sja1000_cs_n <= 1'b1;
						RDflag <= 1'b0; 
						RD_finish<= 1'b0;

							if(rd_trig_r) 
								begin
									st <= S1R;
								end
							
					end 
				
			 S1R:
				 begin 
				 
							 RDflag <= 1'b1;
							 st <= S2R;
				 
				 end
			 
			 S2R:
				 begin
				 
							 chip_oe <= 1'b1; 
							 st <= S3R; 
				 
				 end 
			 
			 S3R: 
				 begin 
				 
							 sja1000_data_wr <= RDaddr; 
							 st <= S4R; 
				 
				 end 
			 
			 S4R:
				 begin 
				 
							 sja1000_ale <= 1'b1;
							 st <= S5R; 
				 
				 end 
			 
			 S5R: 
				 begin
				 
							st <= S6R;
					 
				 end 
			 
			 S6R:
				 begin 
				 
							 sja1000_ale <= 1'b0; 
							 chip_oe <= 1'b0;
							 st <= S7R; 

				 end
			 
			 S7R:
				 begin

							 sja1000_cs_n <= 1'b0;
							 sja1000_dir_1out <= 1'b0;
							 st <= S8R; 

				 end 
			 
			 S8R: 
				 begin 
				 
							 sja1000_rd_n <= 1'b0;
							 st <= S9R;

				 end 
			 
			 S9R: 
				 begin
				 
							st <= S10R;
					 
				 end 

			 S10R: 
				 begin
				 
							 read_data <= i_sja1000_data_rd;
							 st <= S11R;
				 
				 end 
			 
			 S11R: 
				 begin 
				 
							 sja1000_rd_n <= 1'b1; 
							 st <= S12R; 

				 end 
			 
			 S12R:
				 begin

							 sja1000_cs_n <= 1'b1;
							 st <= S13R; 

				 end 
			 
			 S13R: 
				 begin 
				 
							st <= S14R; 

				 end 
			 
			 S14R: 
				 begin 
				 
							 chip_oe <= 1'b0; 
							 st <= S15R; 

				 end 
			 
			 S15R: 
				 begin
				 
							 RD_finish<= 1'b1; 
							 st <= S16R; 
				 
				 end 
			 
			 S16R: 
				 begin
				 
							 RDflag <= 1'b0; 
							 RD_finish<= 1'b0;
							 st <= IDLER; 
				 
				 end
			 
			 default: 
				begin 
					st<=IDLER;
				end 
			 
		 endcase 
		 
	end 
	
end




assign o_RDflag = RDflag;
assign o_RD_finish = RD_finish;


always @(posedge i_clk)
 begin
 
	if(i_rst) 
		begin 
			o_read_data <= 8'b0;
		end

	else if (RD_finish) 
		begin 
			o_read_data <= read_data; 
		end 
	
end 
	
	
	
	

assign o_chip_oe =  RDflag? chip_oe:1'd0;
assign o_sja1000_data_wr = RDflag? sja1000_data_wr:8'd0;
assign o_sja1000_ale = RDflag? sja1000_ale:1'd0;
assign o_sja1000_rd_n = RDflag? sja1000_rd_n:1'd1;
assign o_sja1000_cs_n = RDflag? sja1000_cs_n:1'd1;
assign o_sja1000_dir_1out = RDflag? sja1000_dir_1out:1'd1;








endmodule
